package com.opennews.openplatform.myspringbootcore.helper;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@RequiredArgsConstructor
@Component
public class HttpRequestHelper {
    private final RestTemplate restTemplate;

    /**
     * Makes an HTTP GET request.
     *
     * @param baseUrl  The root of the URI (e.g., http://192.168.1.240:8080).
     * @param url      The rest of the URL (e.g., /smart-farm-api/smsCode/sendAuthCode).
     * @param headers  Map containing HTTP request header data.
     * @param params   Map containing query parameters.
     * @param bodyType The type of data to be returned (e.g., String, Map).
     * @param <T>      The generic type of the response body.
     * @return The response body of type T.
     */
    public <T> T get(String baseUrl, String url, Map<String, String> headers, Map<String, Object> params, Class<T> bodyType) {
        // Constructs the full URL with query parameters.
        StringBuilder fullUrl = new StringBuilder(baseUrl + url);

        if (params != null && !params.isEmpty()) {
            fullUrl.append("?");
            params.forEach((key, value) -> fullUrl.append(key).append("=").append(value).append("&"));

            // Removes trailing "&".
            fullUrl.setLength(fullUrl.length() - 1);
        }

        // Sets the headers.
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);

        // Makes the GET request.
        ResponseEntity<T> response = restTemplate.exchange(
                fullUrl.toString(),
                HttpMethod.GET,
                new org.springframework.http.HttpEntity<>(httpHeaders),
                bodyType
        );

        return response.getBody();
    }

    /**
     * Makes an HTTP GET request and returns the response as a Map.
     *
     * @param baseUrl The root of the URI.
     * @param url     The rest of the URL.
     * @param headers Map containing HTTP request header data.
     * @param params  Map containing query parameters.
     * @return The response body as a Map.
     */
    public Map<String, Object> get(String baseUrl, String url, Map<String, String> headers, Map<String, Object> params) {
        return get(baseUrl, url, headers, params, Map.class);
    }

    /**
     * Makes an HTTP POST request.
     *
     * @param baseUrl  The root of the URI.
     * @param url      The rest of the URL.
     * @param headers  Map containing HTTP request header data.
     * @param body     The HTTP request body.
     * @param bodyType The type of data to be returned (e.g., String, Map).
     * @param <T>      The generic type of the response body.
     * @return The response body of type T.
     */
    public <T> T post(String baseUrl, String url, Map<String, String> headers, Object body, Class<T> bodyType) {
        // Sets the headers
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);

        // Makes the POST request.
        ResponseEntity<T> response = restTemplate.exchange(
                baseUrl + url,
                HttpMethod.POST,
                new org.springframework.http.HttpEntity<>(body, httpHeaders),
                bodyType
        );

        return response.getBody();
    }

    /**
     * Makes an HTTP POST request and returns the response as a Map.
     *
     * @param baseUrl The root of the URI.
     * @param url     The rest of the URL.
     * @param headers Map containing HTTP request header data.
     * @param body    The HTTP request body.
     * @return The response body as a Map.
     */
    public Map<String, Object> post(String baseUrl, String url, Map<String, String> headers, Map<String, Object> body) {
        return post(baseUrl, url, headers, body, Map.class);
    }
}
